---
title: 历史记录
icon: '#pro/History'
---

<MetaData
  lang="zh-CN"
  isPro
  meta={{
    preset: [{
      client: '@univerjs/preset-docs-collaboration',
      locale: '@univerjs/preset-docs-collaboration/locales/zh-CN',
      style: '@univerjs/preset-docs-collaboration/lib/index.css',
    }],
    plugins: [{
      client: '@univerjs-pro/edit-history-loader',
    }, {
      client: '@univerjs-pro/edit-history-viewer',
      facade: '@univerjs-pro/edit-history-viewer/locale/zh-CN',
      style: '@univerjs-pro/edit-history-viewer/lib/index.css',
    }],
    server: '是',
  }}
/>

<Callout type="warning" title="注意事项">
  历史记录功能需要 Univer 服务端支持，请确保你已经正确安装并配置了 Univer 服务端。具体请参考：[升级到 Pro](/guides/sheets/getting-started/pro)
</Callout>

历史记录功能允许用户查看和恢复文档的历史版本，支持多种过滤和搜索方式，帮助用户高效管理文档内容。

<Callout type="warning" title="注意事项">
  历史记录功能内部创建了一个独立的 Univer 实例来处理历史记录的加载和展示。如果你需要对历史记录的 Univer 实例进行操作或配置（如修改接口请求头、注册插件等），请参考[获取历史记录的 Univer 实例](#get-edit-history-univer-instance)部分。
</Callout>

## 预设模式

### 安装

<Callout>
  @univerjs/preset-sheets-advanced 的 `UniverSheetsAdvancedPreset` 预设在运行时依赖 `UniverSheetsDrawingPreset` 预设，请先安装 @univerjs/preset-sheets-drawing。
</Callout>

```package-install
npm install @univerjs/preset-sheets-drawing @univerjs/preset-sheets-advanced
```

### 使用

```typescript
import { UniverSheetsAdvancedPreset } from '@univerjs/preset-sheets-advanced' // [!code ++]
import UniverPresetSheetsAdvancedZhCN from '@univerjs/preset-sheets-advanced/locales/zh-CN' // [!code ++]
import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'
import UniverPresetSheetsCoreZhCN from '@univerjs/preset-sheets-core/locales/zh-CN'
import { UniverSheetsDrawingPreset } from '@univerjs/preset-sheets-drawing' // [!code ++]
import UniverPresetSheetsDrawingZhCN from '@univerjs/preset-sheets-drawing/locales/zh-CN' // [!code ++]
import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'

import '@univerjs/preset-sheets-core/lib/index.css'
import '@univerjs/preset-sheets-drawing/lib/index.css' // [!code ++]
import '@univerjs/preset-sheets-advanced/lib/index.css' // [!code ++]

const { univerAPI } = createUniver({
  locale: LocaleType.ZH_CN,
  locales: {
    [LocaleType.ZH_CN]: mergeLocales(
      UniverPresetSheetsCoreZhCN,
      UniverPresetSheetsDrawingZhCN, // [!code ++]
      UniverPresetSheetsAdvancedZhCN, // [!code ++]
    ),
  },
  presets: [
    UniverSheetsCorePreset(),
    UniverSheetsDrawingPreset(), // [!code ++]
    UniverSheetsAdvancedPreset({ // [!code ++]
      universerEndpoint: 'http://localhost:3010', // [!code ++]
    }), // [!code ++]
  ],
})
```

如果你拥有 Univer 的商业许可证，请参考[在客户端使用许可证](/guides/pro/license#在预设模式中使用)进行配置。

### 预设与配置

`UniverSheetsAdvancedPreset` 配置项：

```typescript
interface IUniverSheetsAdvancedPresetConfig {
  // Univer Server 的端口地址
  universerEndpoint?: string
}
```

## 插件模式

### 安装

```package-install
npm install @univerjs-pro/edit-history-viewer @univerjs-pro/edit-history-loader
```

### 使用

```typescript
import { UniverEditHistoryLoaderPlugin } from '@univerjs-pro/edit-history-loader' // [!code ++]
import EditHistoryViewerZhCN from '@univerjs-pro/edit-history-viewer/locale/zh-CN' // [!code ++]
import { LocaleType, mergeLocales, Univer } from '@univerjs/core'

import '@univerjs-pro/edit-history-viewer/lib/index.css' // [!code ++]

const univer = new Univer({
  locale: LocaleType.ZH_CN,
  locales: {
    [LocaleType.ZH_CN]: mergeLocales(
      EditHistoryViewerZhCN, // [!code ++]
    ),
  },
})

univer.registerPlugin(UniverEditHistoryLoaderPlugin, { // [!code ++]
  univerContainerId: 'your-univer-container-id', // [!code ++]
}) // [!code ++]
```

如果你拥有 Univer 的商业许可证，请参考[在客户端使用许可证](/guides/pro/license#在插件模式中使用)进行配置。

### 插件与配置

`UniverEditHistoryLoaderPlugin` 配置项：

```typescript
interface IUniverEditHistoryLoaderConfig {
  univerContainerId?: string
  // 历史记录列表的服务器地址
  historyListServerUrl?: string
}
```

启动历史记录时，`UniverEditHistoryLoaderPlugin` 会加载一个新的 Univer 实例挂载指定 DOM 节点上。因此在注册时，需要提供合适的 DOM 节点 id（如原 Univer 实例的 Container），以达到历史记录面板覆盖原 Univer 面板的目的。若节点 id 未指定，则默认为  `univer-container`。

如果需要修改历史记录列表的服务器地址，可以通过 `historyListServerUrl` 配置项进行设置，默认为 `/universer-api/history`。

## 获取历史记录的 Univer 实例 `historyUniver` [#get-edit-history-univer-instance]

<Callout title="友情提示">
  历史记录的 Univer 实例只在第一次打开历史记录面板时创建。
</Callout>

如果你需要对历史记录的 Univer 实例进行操作或配置（如修改接口请求头、注册插件等），可以通过 `HistoryLoaderService` 获取到该实例。

<Tabs items={['预设模式', '插件模式']}>
  <Tab>
    ```typescript
    import { HistoryLoaderService } from '@univerjs/preset-sheets-collaboration'

    const disposable = univerAPI.addEvent(univerAPI.Event.LifeCycleChanged, ({ stage }) => {
      if (stage === univerAPI.Enum.LifecycleStages.Steady) {
        const injector = univer.__getInjector()
        const historyLoaderService = injector.get(HistoryLoaderService)

        historyLoaderService.historyUniver$.subscribe((historyUniver) => {
          if (!historyUniver) return

          // 在这里可以使用 historyUniver 实例进行操作
        })
      }
    })

    // 移除事件监听器，使用 `disposable.dispose()`
    ```
  </Tab>
  <Tab>
    ```typescript
    import { HistoryLoaderService } from '@univerjs-pro/edit-history-loader'

    const disposable = univerAPI.addEvent(univerAPI.Event.LifeCycleChanged, ({ stage }) => {
      if (stage === univerAPI.Enum.LifecycleStages.Steady) {
        const injector = univer.__getInjector()
        const historyLoaderService = injector.get(HistoryLoaderService)

        historyLoaderService.historyUniver$.subscribe((historyUniver) => {
          // 在这里可以使用 historyUniver 实例进行操作
        })
      }
    })

    // 移除事件监听器，使用 `disposable.dispose()`
    ```
  </Tab>
</Tabs>

### 第三方插件适配

历史记录的 Univer 实例中只会默认加载官方的 Plugin。为业务需求开发的第三方 Feature Plugin 需要被注册到 `HistoryLoaderService` 后，才会被正确的显示在历史记录中。

```typescript
const injector = univer.__getInjector()
const historyLoaderService = injector.get(HistoryLoaderService)

// [!code focus:4]
// 和 PluginService 的注册方式一致，历史记录的 Univer 实例在新建后会按照以下配置来注册对应 Plugin
historyLoaderService.registerPlugin(YourPlugin, YourPluginConfig)
// 配置官方已注册的 Plugin, 需设置 true 参数表示覆盖原配置
historyLoaderService.registerPlugin(ExamplePlugin, ExamplePluginConfig, true)
```
